package com.kmb.commons.utils;

import com.kmb.business.Constants;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

public class DateUtil {
    /**
     * 年 格式化
     */
    public static final String YEAR_MONTH = "yyyy-MM";
    /**
     * 日期 格式化
     */
    public static final String DATE = "yyyy-MM-dd";
    /**
     * 日期时间 格式化
     */
    public static final String TIMESTAMP = "yyyy-MM-dd HH:mm:ss";
    /**
     * 日期时间 格式化
     */
    public static final String TIMESTAMPNOW = "yyyyMMddHHmmss";
    /**
     * 日期时间 格式化 毫秒时间
     */
    public static final String SECONDTIMESTAMPNOW = "yyyyMMddHHmmssSSS";
    /**
     * 日期时间 格式化
     */
    public static final String DATENOG = "yyyyMMdd";
    /**
     * 日期时间 格式化
     */
    public static final String TIMESTAMP_MS = "yyyy-MM-dd HH:mm:ss.SSS";
    /**
     * 时间 格式化
     */
    public static final String TIME = "HH:mm:ss";
    /**
     * 时间 格式化
     */
    public static final String SECONDS = "HH:mm:ss.SSS";
    /**
     * 时间 格式化
     */
    public static final String TIME_T = "T";
    /**
     * 时间 格式化
     */
    public static final String TIME_Z = "Z";
    /**
     * 日期时间 格式化
     */
    public static final String TIMESTAMP_MS_TZ = "yyyy-MM-ddTHH:mm:ss.SSSZ";

    /**
     * 查询条件 格式时间到时分秒
     */
    public static final String FORMAT_HMS = " 00:00:00";
    /**
     * 查询条件 格式时间到时分秒
     */
    public static final String FORMAT_HMS_END = " 23:59:59";

    /**
     * 把日期字符串格式化成日期类型
     *
     * @param dateStr
     * @param format
     * @return
     */
    public static Date convert2Date(String dateStr, String format) {
        SimpleDateFormat simple = new SimpleDateFormat(format);
        try {
            simple.setLenient(false);
            return simple.parse(dateStr);
        } catch (Exception e) {
            return null;
        }
    }

    public static String getDateNow() {
        return dateToString(new Date(), Constants.DATE);
    }

    public static String getDateNowNoCrossBar() {
        return dateToString(new Date(), Constants.DATENOG);
    }

    public static String getDateNowTime() {
        return dateToString(new Date(), Constants.TIMESTAMPNOW);
    }

    /**
     * 把日期类型格式化成字符串
     *
     * @param date
     * @param format
     * @return
     */
    public static String convert2String(Date date, String format) {
        SimpleDateFormat formater = new SimpleDateFormat(format);
        try {
            return formater.format(date);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 获取当前时间- 绝对秒
     *
     * @return
     */
    public static long getCurrentLongTime() {
        return System.currentTimeMillis() / Constants.NUMBER_OF_TIME;
    }

    /**
     * 把日期类型格式化成字符串（yyyy-MM-ddTHH:mm:ss.SSSZ）
     *
     * @param date
     * @return
     */
    public static String convertStrTZ(Date date) {
        SimpleDateFormat dateFormater = new SimpleDateFormat(DATE);
        SimpleDateFormat secondFormater = new SimpleDateFormat(SECONDS);
        try {
            String dateStr = dateFormater.format(date);
            String secondStr = secondFormater.format(date);
            return dateStr + TIME_T + secondStr + TIME_Z;
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 转sql的time格式
     *
     * @param date
     * @return
     */
    public static java.sql.Timestamp convertSqlTime(Date date) {
        java.sql.Timestamp timestamp = new java.sql.Timestamp(date.getTime());
        return timestamp;
    }

    /**
     * 转sql的日期格式
     *
     * @param date
     * @return
     */
    public static java.sql.Date convertSqlDate(Date date) {
        java.sql.Date Datetamp = new java.sql.Date(date.getTime());
        return Datetamp;
    }

    /**
     * 日期转换为指定格式的字符
     *
     * @param date       日期
     * @param dateFormat 日期格式
     * @return
     */
    public static String dateToString(Date date, String dateFormat) {
        SimpleDateFormat df = null;
        String returnValue = "";
        if (date != null) {
            df = new SimpleDateFormat(dateFormat);
            returnValue = df.format(date);
        }
        return returnValue;
    }

    /**
     * 日期字符串转换为日期格式
     *
     * @param dateStr    日期字符串
     * @param dateFormat 日期格式
     * @return
     * @throws ParseException
     */
    public static Date stringToDate(String dateStr, String dateFormat) throws ParseException {
        SimpleDateFormat sf = new SimpleDateFormat(dateFormat);
        try {
            return sf.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
            throw new ParseException("日期解析错误！", 0);
        }
    }


    /**
     * 在原日期的基础上增加分钟数
     *
     * @param date
     * @param i
     * @return
     */
    public static Date addMinuteOfDate(Date date, int i) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.MINUTE, i);
        Date newDate = c.getTime();
        return newDate;
    }

    /**
     * 在原日期的基础上增加秒数
     *
     * @param date
     * @param i
     * @return
     */
    public static Date addSecondOfDate(Date date, int i) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.SECOND, i);
        Date newDate = c.getTime();
        return newDate;
    }

    /**
     * 获取当前日期
     *
     * @param format
     * @return
     */
    public static String getCurrentDate(String format) {
        return new SimpleDateFormat(format).format(new Date());
    }

    /**
     * 获取当前日期
     *
     * @param format
     * @return
     */
    public static String getDate(String format, Date date) {
        return new SimpleDateFormat(format).format(date);
    }

    /**
     * 获取时间戳
     *
     * @return
     */
    public static long getTimestamp() {
        return System.currentTimeMillis();
    }

    /**
     * 获取月份的天数
     *
     * @param year
     * @param month
     * @return
     */
    public static int getDaysOfMonth(int year, int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(year, month - 1, 1);
        return calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
    }

    /**
     * 获取日期的年
     *
     * @param date
     * @return
     */
    public static int getYear(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.YEAR);
    }

    /**
     * 获取日期的月
     *
     * @param date
     * @return
     */
    public static int getMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.MONTH) + 1;
    }

    /**
     * 获取当前日期的季度
     *
     * @param date
     * @return
     */
    public static String getQuarterStr(Date date) {

        Calendar monthC = Calendar.getInstance();
        monthC.setTime(date);
        int month = monthC.get(Calendar.MONTH) + 1;
        String quarter = "";
        if (month >= 1 && month <= Number.NUM_3) {
            quarter = "一";
        } else if (month >= Number.NUM_4 && month <= Number.NUM_6) {
            quarter = "二";
        } else if (month >= Number.NUM_7 && month <= Number.NUM_9) {
            quarter = "三";
        } else {
            quarter = "四";
        }
        return quarter;
    }

    /**
     * 获取日期的日
     *
     * @param date
     * @return
     */
    public static int getDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.DATE);
    }

    /**
     * 获取日期的时
     *
     * @param date
     * @return
     */
    public static int getHour(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.HOUR);
    }

    /**
     * 获取日期的分种
     *
     * @param date
     * @return
     */
    public static int getMinute(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.MINUTE);
    }

    /**
     * 获取日期的秒
     *
     * @param date
     * @return
     */
    public static int getSecond(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.SECOND);
    }

    /**
     * 获取星期几
     *
     * @param date
     * @return
     */
    public static int getWeekDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
        return dayOfWeek - 1;
    }

    /**
     * 获取哪一年共有多少周
     *
     * @param year
     * @return
     */
    public static int getMaxWeekNumOfYear(int year) {
        Calendar c = new GregorianCalendar();
        c.set(year, Calendar.DECEMBER, Number.NUM_31, Number.NUM_23, Number.NUM_59, Number.NUM_59);
        return getWeekNumOfYear(c.getTime());
    }

    /**
     * 取得某天是一年中的多少周
     *
     * @param date
     * @return
     */
    public static int getWeekNumOfYear(Date date) {
        Calendar c = new GregorianCalendar();
        c.setFirstDayOfWeek(Calendar.MONDAY);
        c.setMinimalDaysInFirstWeek(Number.NUM_7);
        c.setTime(date);
        return c.get(Calendar.WEEK_OF_YEAR);
    }

    /**
     * 取得某天所在周的第一天
     *
     * @return
     */
    public static Date getFirstDayOfWeek(Date date) {
        Calendar c = new GregorianCalendar();
        c.setFirstDayOfWeek(Calendar.MONDAY);
        c.setTime(date);
        c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek());
        return c.getTime();
    }

    /**
     * 取得某天所在周的最后一天
     *
     * @param date
     * @return
     */
    public static Date getLastDayOfWeek(Date date) {
        Calendar c = new GregorianCalendar();
        c.setFirstDayOfWeek(Calendar.MONDAY);
        c.setTime(date);
        c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek() + Number.NUM_6);
        return c.getTime();
    }

    /**
     * 取得某年某周的第一天 对于交叉:2008-12-29到2009-01-04属于2008年的最后一周,2009-01-05为2009年第一周的第一天
     *
     * @param year
     * @param week
     * @return
     */
    public static Date getFirstDayOfWeek(int year, int week) {
        Calendar calFirst = Calendar.getInstance();
        calFirst.set(year, 0, Number.NUM_7);
        Date firstDate = getFirstDayOfWeek(calFirst.getTime());

        Calendar firstDateCal = Calendar.getInstance();
        firstDateCal.setTime(firstDate);

        Calendar c = new GregorianCalendar();
        c.set(Calendar.YEAR, year);
        c.set(Calendar.MONTH, Calendar.JANUARY);
        c.set(Calendar.DATE, firstDateCal.get(Calendar.DATE));

        Calendar cal = (GregorianCalendar) c.clone();
        cal.add(Calendar.DATE, (week - 1) * Number.NUM_7);
        firstDate = getFirstDayOfWeek(cal.getTime());

        return firstDate;
    }

    /**
     * 取得某年某周的最后一天 对于交叉:2008-12-29到2009-01-04属于2008年的最后一周, 2009-01-04为
     * 2008年最后一周的最后一天
     *
     * @param year
     * @param week
     * @return
     */
    public static Date getLastDayOfWeek(int year, int week) {
        Calendar calLast = Calendar.getInstance();
        calLast.set(year, 0, Number.NUM_7);
        Date firstDate = getLastDayOfWeek(calLast.getTime());

        Calendar firstDateCal = Calendar.getInstance();
        firstDateCal.setTime(firstDate);

        Calendar c = new GregorianCalendar();
        c.set(Calendar.YEAR, year);
        c.set(Calendar.MONTH, Calendar.JANUARY);
        c.set(Calendar.DATE, firstDateCal.get(Calendar.DATE));

        Calendar cal = (GregorianCalendar) c.clone();
        cal.add(Calendar.DATE, (week - 1) * Number.NUM_7);
        Date lastDate = getLastDayOfWeek(cal.getTime());

        return lastDate;
    }


    private static Date add(Date date, int calendarField, int amount) {
        if (date == null) {
            throw new IllegalArgumentException("The date must not be null");
        } else {
            Calendar c = Calendar.getInstance();
            c.setTime(date);
            c.add(calendarField, amount);
            return c.getTime();
        }
    }

    /*
     * 1则代表的是对年份操作， 2是对月份操作， 3是对星期操作， 5是对日期操作， 11是对小时操作， 12是对分钟操作， 13是对秒操作，
     * 14是对毫秒操作
     */

    /**
     * 增加年
     *
     * @param date
     * @param amount
     * @return
     */
    public static Date addYears(Date date, int amount) {
        return add(date, 1, amount);
    }

    /**
     * 增加月
     *
     * @param date
     * @param amount
     * @return
     */
    public static Date addMonths(Date date, int amount) {
        return add(date, Number.NUM_2, amount);
    }

    /**
     * 增加周
     *
     * @param date
     * @param amount
     * @return
     */
    public static Date addWeeks(Date date, int amount) {
        return add(date, Number.NUM_3, amount);
    }

    /**
     * 增加天
     *
     * @param date
     * @param amount
     * @return
     */
    public static Date addDays(Date date, int amount) {
        return add(date, Number.NUM_5, amount);
    }

    /**
     * 增加时
     *
     * @param date
     * @param amount
     * @return
     */
    public static Date addHours(Date date, int amount) {
        return add(date, Number.NUM_11, amount);
    }

    /**
     * 增加分
     *
     * @param date
     * @param amount
     * @return
     */
    public static Date addMinutes(Date date, int amount) {
        return add(date, Number.NUM_12, amount);
    }

    /**
     * 增加秒
     *
     * @param date
     * @param amount
     * @return
     */
    public static Date addSeconds(Date date, int amount) {
        return add(date, Number.NUM_13, amount);
    }

    /**
     * 增加毫秒
     *
     * @param date
     * @param amount
     * @return
     */
    public static Date addMilliseconds(Date date, int amount) {
        return add(date, Number.NUM_14, amount);
    }


    /**
     * time差
     *
     * @param before
     * @param after
     * @return
     */
    public static long diffTimes(Date before, Date after) {
        return after.getTime() - before.getTime();
    }

    /**
     * 秒差
     *
     * @param before
     * @param after
     * @return
     */
    public static long diffSecond(Date before, Date after) {
        return (after.getTime() - before.getTime()) / Number.NUM_1000;
    }

    /**
     * 分种差
     *
     * @param before
     * @param after
     * @return
     */
    public static int diffMinute(Date before, Date after) {
        return (int) (after.getTime() - before.getTime()) / Number.NUM_1000 / Number.NUM_60;
    }

    /**
     * 时差
     *
     * @param before
     * @param after
     * @return
     */
    public static int diffHour(Date before, Date after) {
        return (int) (after.getTime() - before.getTime()) / Number.NUM_1000 / Number.NUM_60 / Number.NUM_60;
    }

    /**
     * 天数差
     *
     * @return
     */
    public static int diffDay(Date before, Date after) {
        return Integer.parseInt(String.valueOf(((after.getTime() - before.getTime()) / Number.NUM_86400000)));
    }

    /**
     * 月差
     *
     * @param before
     * @param after
     * @return
     */
    public static int diffMonth(Date before, Date after) {
        int monthAll = 0;
        int yearsX = diffYear(before, after);
        Calendar c1 = Calendar.getInstance();
        Calendar c2 = Calendar.getInstance();
        c1.setTime(before);
        c2.setTime(after);
        int monthsX = c2.get(Calendar.MONTH) - c1.get(Calendar.MONTH);
        monthAll = yearsX * Number.NUM_12 + monthsX;
        int daysX = c2.get(Calendar.DATE) - c1.get(Calendar.DATE);
        if (daysX > 0) {
            monthAll = monthAll + 1;
        }
        return monthAll;
    }

    /**
     * 年差
     *
     * @param before
     * @param after
     * @return
     */
    public static int diffYear(Date before, Date after) {
        return getYear(after) - getYear(before);
    }

    /**
     * 设置23:59:59
     *
     * @param date
     * @return
     */
    public static Date setEndDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, Number.NUM_23);
        calendar.set(Calendar.MINUTE, Number.NUM_59);
        calendar.set(Calendar.SECOND, Number.NUM_59);
        return calendar.getTime();
    }

    /**
     * 设置00:00:00
     *
     * @param date
     * @return
     */
    public static Date setStartDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }

    /**
     * 获取上周的时间
     *
     * @param date
     * @return
     */
    public static Date getLastWeekDay(Date date) {
        Calendar ca = Calendar.getInstance();
        ca.setTime(date);
        ca.add(Calendar.DATE, -Number.NUM_7);
        return ca.getTime();
    }

    /**
     * 获取上月的时间
     *
     * @param date
     * @return
     */
    public static Date getLastMonthDay(Date date) {
        Calendar ca = Calendar.getInstance();
        ca.setTime(date);
        ca.add(Calendar.MONTH, -1);
        return ca.getTime();
    }

    /**
     * 获取上一季度的时间
     *
     * @param date
     * @return
     */
    public static Date getLastQuarterDay(Date date) {
        Calendar ca = Calendar.getInstance();
        ca.setTime(date);
        ca.add(Calendar.MONTH, -Number.NUM_3);
        return ca.getTime();
    }

    /**
     * 获取上一年的时间
     *
     * @param date
     * @return
     */
    public static Date getLastYearDay(Date date) {
        Calendar ca = Calendar.getInstance();
        ca.setTime(date);
        ca.add(Calendar.YEAR, -1);
        return ca.getTime();
    }

    /**
     * 获取昨天的时间
     *
     * @param date
     * @return
     */
    public static Date getYesTerDay(Date date) {
        Calendar ca = Calendar.getInstance();
        ca.setTime(date);
        ca.add(Calendar.HOUR, -Number.NUM_24);
        return ca.getTime();
    }

    /**
     * 获取前n天的日期
     *
     * @param date
     * @return
     */
    public static Date getBeforeDay(Date date, int count) {
        Calendar ca = Calendar.getInstance();
        ca.setTime(date);
        ca.add(Calendar.DATE, -1 * count);
        return ca.getTime();
    }

    /**
     * 获取当前日期所在月 的 第一天
     *
     * @param date
     * @return
     */
    public static Date getFirstDateOfMonth(Date date) {
        Calendar ca = Calendar.getInstance();
        ca.setTime(date);
        ca.add(Calendar.MONTH, 0);
        ca.set(Calendar.DAY_OF_MONTH, 1);
        return ca.getTime();
    }

    /**
     * 获取当前日期所在季度 的  第一天
     *
     * @param date
     * @return
     */
    public static Date getFirstDateOfQuarter(Date date) {
        Calendar monthC = Calendar.getInstance();
        monthC.setTime(date);
        Calendar quarterC = Calendar.getInstance();
        int month = monthC.get(Calendar.MONTH) + 1;
        int quarter = 0;
        if (month >= 1 && month <= Number.NUM_3) {
            quarter = 1;
        } else if (month >= Number.NUM_4 && month <= Number.NUM_6) {
            quarter = Number.NUM_2;
        } else if (month >= Number.NUM_7 && month <= Number.NUM_9) {
            quarter = Number.NUM_3;
        } else {
            quarter = Number.NUM_4;
        }
        switch (quarter) {
            case 1:
                quarterC.set(Calendar.MONTH, 0);
                quarterC.set(Calendar.DATE, 1);
                break;
            case Number.NUM_2:
                quarterC.set(Calendar.MONTH, Number.NUM_3);
                quarterC.set(Calendar.DATE, 1);
                break;
            case Number.NUM_3:
                quarterC.set(Calendar.MONTH, Number.NUM_6);
                quarterC.set(Calendar.DATE, 1);
                break;
            case Number.NUM_4:
                quarterC.set(Calendar.MONTH, Number.NUM_9);
                quarterC.set(Calendar.DATE, 1);
                break;
            default:
                break;
        }
        return quarterC.getTime();
    }

    /**
     * 获取今日凌晨的时间
     *
     * @param nowDate
     * @return
     */
    public static Date getToDayStartTime(Date nowDate) throws ParseException {
        String dateStr = DateUtil.dateToString(nowDate, DATE);
        try {
            Date startTime = DateUtil.stringToDate(dateStr + Constants.FORMAT_HMS, Constants.TIMESTAMP);
            return startTime;
        } catch (ParseException e) {
            e.printStackTrace();
            throw new ParseException("日期解析错误！", 0);
        }
    }

    /**
     * 将数字转成String，只取两位
     *
     * @param i
     * @return
     */
    public static String convertIntToStr(int i) {
        if (StringUtil.isEmpty(i)) {
            return "00";
        }
        if (i > 0 && 1 < Number.NUM_10) {
            return "0" + i;
        }
        if (i > Number.NUM_9 && i < Number.NUM_100) {
            return String.valueOf(i);
        }
        if (1 >= Number.NUM_100) {
            return String.valueOf(i).substring(0, Number.NUM_2);
        }
        return "00";
    }


}
